﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Binalyse.Memory;

namespace Binalyse
{
    public partial class MainForm : Form
    {
        private MemalyseDocument m_memDocument = new MemalyseDocument();
        private string strProgram = " - Binalyse V1.0 Beta";
        private int nHighLightBlockIndex = 0;
        private string strPathName = "";

        public MainForm()
        {
            InitializeComponent();
            this.Text = m_memDocument.Title + strProgram;
            label_byte.Text = "";
            label_ansiChar.Text = "";
            label_UniChar.Text = "";
            label_short.Text = "";
            label_single.Text = "";
            label_double.Text = "";
        }

        private void hexViewer1_SelectedIndexChangedEvent(object sender)
        {
            label_byte.Text = "";
            label_ansiChar.Text = "";
            label_UniChar.Text = "";
            label_short.Text = "";
            label_single.Text = "";
            label_double.Text = "";

            if (hexViewer.SelectedIndex != -1)
            {
                if (hexViewer.Data != null)
                {
                    int len = hexViewer.Data.Length - hexViewer.SelectedIndex;
                    int index = hexViewer.SelectedIndex;
                    byte[] data = hexViewer.Data;

                    if (len >= 1)
                    {
                        label_byte.Text = string.Format("{0}/{0:X2}/{1}", data[index], (int)data[index]);
                        if (data[index] > 32 && data[index] < 127)
                        {
                            label_ansiChar.Text = ((char)data[index]).ToString();
                        }
                        else
                        {
                            label_ansiChar.Text = "不可打印的字符";
                        }
                    }
                    if (len >= 2)
                    {
                        label_UniChar.Text = BitConverter.ToChar(data, index).ToString();
                        label_short.Text = string.Format("{0}/{1}/{1:X4}", BitConverter.ToInt16(data, index), BitConverter.ToUInt16(data, index));
                    }
                    if (len >= 4)
                    {
                        label_int.Text = string.Format("{0}/{1}/{1:X8}", BitConverter.ToInt32(data, index), BitConverter.ToUInt32(data, index));
                        label_single.Text = string.Format("{0}", BitConverter.ToSingle(data, index));
                    }
                    if (len >= 8)
                    {
                        label_double.Text = string.Format("{0}", BitConverter.ToDouble(data, index));
                        label_int64.Text = string.Format("{0}/{1}", BitConverter.ToInt64(data, index), BitConverter.ToUInt64(data, index));
                    }
                }
            }
        }

        private void processesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SelectProcessDialog spd = new SelectProcessDialog();
            if (spd.ShowDialog() == DialogResult.OK)
            {
                m_memDocument.AnalyseMemory(spd.ProcessId, spd.ProcessName, spd.ModuleAddress, spd.ModuleName);
                memoryListBox.Items.Clear();
                foreach (PESection pes in m_memDocument.Sections)
                {
                    memoryListBox.Items.Add(pes);
                }
                foreach (Heap heap in m_memDocument.Heaps)
                {
                    memoryListBox.Items.Add(heap);
                }
                this.Text = m_memDocument.Title + strProgram;
            }
        }

        private void memoryListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (memoryListBox.SelectedIndex != -1)
            {
                if (memoryListBox.SelectedItem is PESection)
                {
                    hexViewer.Data = ((PESection)memoryListBox.SelectedItem).Data;
                }
                else if (memoryListBox.SelectedItem is Heap)
                {
                    Heap item = (Heap)memoryListBox.SelectedItem;
                    hexViewer.Data = item.Data;
                    nHighLightBlockIndex = 0;
                    if (item.Blocks.Count > 0)
                    {
                        hexViewer.SetHighLight(item.Blocks[nHighLightBlockIndex].StartIndex - 8, 
                            item.Blocks[nHighLightBlockIndex].Length + 8);
                    }
                }
            }
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (strPathName == "")
            {
                saveFileDialog.Filter = "Binalyse File|*.binf|All Files|*.*";
                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    if (m_memDocument.Save(saveFileDialog.FileName))
                    {
                        strPathName = saveFileDialog.FileName;
                    }
                }
            }
            else
            {
                m_memDocument.Save(strPathName);
            }
        }

        private void saveCurToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (memoryListBox.SelectedIndex == -1)
            {
                MessageBox.Show("请选择一个内存块!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            saveFileDialog.Filter = "All Files|*.*";
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                byte[] data = null;
                if (memoryListBox.SelectedItem is PESection)
                {
                    data = ((PESection)memoryListBox.SelectedItem).Data;
                }
                else if (memoryListBox.SelectedItem is Heap)
                {
                    data = ((Heap)memoryListBox.SelectedItem).Data;
                }
                else
                {
                    MessageBox.Show("可保存的数据为空!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                try
                {
                    using (StreamWriter sw = new StreamWriter(saveFileDialog.FileName))
                    {
                        sw.Write(data);
                    }
                }
                catch (Exception ex)
                {
                    string strMsg = "保存文件时出错!\r\n错误详情:\r\n";
                    strMsg += ex.Message;
                    MessageBox.Show(strMsg, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog.Filter = "Binalyse File|*.binf|All Files|*.*";
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                m_memDocument.Save(saveFileDialog.FileName);
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

    }
}
